import json
import time

from selenium.common import NoSuchElementException
from selenium.webdriver.support import expected_conditions as EC

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.wait import WebDriverWait

class Train:
    # 读取配置文件信息
    def load_setting(self):
        try:
            with open('settings.txt', 'r') as file:
                settings = {}
                for line in file:
                    key, value = line.strip().split('=', 1)
                    settings[key] = value
            return settings
        except FileNotFoundError:
            print('打开文件出错')
            return None

    def __init__(self):
        # 配置 Chrome 驱动
        service = Service(executable_path='./chromedriver')
        self.driver = webdriver.Chrome(service=service)
        # 12306 登录成功后保存的 Cookie 文件路径
        self.cookies_file = '12306_cookies.json'
        # 12306登录状态
        self.login_status = False
        # 加载配置文件信息
        self.settings = self.load_setting()

    # 保存Cookie
    def save_cookies(self):
        if not self.login_status:
            print("未登录状态，无法保存Cookie")
            return False

        print("开始保存Cookie")

        # 获取当前所有Cookie
        cookies = self.driver.get_cookies()

        # 保存到文件
        try:
            with open(self.cookies_file, 'w') as f:
                json.dump(cookies, f)
            print(f"Cookie已保存到 {self.cookies_file}")
            return True
        except Exception as e:
            print("保存Cookie失败")
            return False

    # 加载Cookie
    def load_cookies(self):
        """加载保存的Cookie"""
        print("尝试加载Cookie")

        try:
            # 访问12306首页
            self.driver.get('https://www.12306.cn/index/')

            # 加载Cookie
            with open(self.cookies_file, 'r') as f:
                cookies = json.load(f)

            for cookie in cookies:
                # 添加前删除可能存在的旧cookie
                self.driver.delete_cookie(cookie['name'])
                self.driver.add_cookie(cookie)

            # 刷新页面
            self.driver.refresh()
            time.sleep(2)

            # 检查是否登录成功
            try:
                self.driver.find_element(By.CLASS_NAME, 'header-nav-login')
                print("Cookie登录成功")
                self.login_status = True
                return True
            except NoSuchElementException:
                print("Cookie登录失败，需要重新登录")
                return False
        except Exception:
            print("加载Cookie失败")
            return False

    # 账号密码登录
    def account_password_login(self):
        # 去到12306登录页面
        self.driver.get('https://kyfw.12306.cn/otn/resources/login.html')

        # .login-hd-code 选择所有class包含login-hd-code的节点
        self.driver.find_element(By.CSS_SELECTOR, '.login-hd-code').click()

        # 等待元素可交互
        WebDriverWait(self.driver, 10).until(
            EC.element_to_be_clickable((By.CSS_SELECTOR, '#J-userName'))
        )
        # 输入用户名
        self.driver.find_element(By.CSS_SELECTOR, '#J-userName').send_keys(self.settings['username'])
        # 输入密码
        self.driver.find_element(By.CSS_SELECTOR, '#J-password').send_keys(self.settings['password'])
        # 点击登录按钮
        self.driver.find_element(By.CSS_SELECTOR, '#J-login').click()
        # 等待元素可交互
        WebDriverWait(self.driver, 10).until(
            EC.element_to_be_clickable((By.CSS_SELECTOR, '#id_card'))
        )
        # 输入身份证后4位
        self.driver.find_element(By.CSS_SELECTOR, '#id_card').send_keys(self.settings['last4'])
        # 点击发送验证码
        self.driver.find_element(By.CSS_SELECTOR, '#verification_code').click()
        verification_code = input('请输入手机上收到的验证码：')
        self.driver.find_element(By.CSS_SELECTOR, '#code').send_keys(verification_code)
        # 点击确定按钮
        self.driver.find_element(By.CSS_SELECTOR, '#sureClick').click()
        # 设置登录状态为成功
        self.login_status = True

    # 扫码登录
    def scan_code_login(self):
        # 去到12306登录页面
        self.driver.get('https://kyfw.12306.cn/otn/resources/login.html')
        # 点击扫码登录
        self.driver.find_element(By.CSS_SELECTOR, '.login-hd-account').click()
        # 等待扫码登录成功
        input('请手动完成扫码验证，然后按下回车键继续...')
        # 设置登录状态为成功
        self.login_status = True

    # 车票查询
    def query_ticket(self):
        # 等待页面中车票预订按键可点击
        WebDriverWait(self.driver, 10).until(
            EC.element_to_be_clickable((By.CSS_SELECTOR, '#link_for_ticket'))
        )
        # 点击车票预订，进入车票查询页面
        self.driver.find_element(By.CSS_SELECTOR, '#link_for_ticket').click()
        # 填写车票基本信息
        # 选择单程
        self.driver.find_element(By.CSS_SELECTOR, '#dc').click()
        self.driver.find_element(By.CSS_SELECTOR,'#fromStationText').click()
        self.driver.find_element(By.CSS_SELECTOR, '#fromStationText').send_keys(self.settings['fromStationText'])
        self.driver.find_element(By.CSS_SELECTOR, '#fromStationText').send_keys(Keys.ENTER)
        self.driver.find_element(By.CSS_SELECTOR, '#toStationText').click()
        self.driver.find_element(By.CSS_SELECTOR, '#toStationText').clear()
        self.driver.find_element(By.CSS_SELECTOR, '#toStationText').send_keys(self.settings['toStationText'])
        self.driver.find_element(By.CSS_SELECTOR, '#toStationText').send_keys(Keys.ENTER)
        self.driver.find_element(By.CSS_SELECTOR, '#train_date').click()
        self.driver.find_element(By.CSS_SELECTOR,'#train_date').clear()
        self.driver.find_element(By.CSS_SELECTOR, '#train_date').send_keys(self.settings['train_date'])
        self.driver.find_element(By.CSS_SELECTOR, '#train_date').send_keys(Keys.ENTER)
        # 选择sf1普通票，sf2学生票
        passenger_type = self.settings['passenger_type']
        if passenger_type == '普通':
            self.driver.find_element(By.CSS_SELECTOR, '#sf1').click()
        elif passenger_type == '学生':
            self.driver.find_element(By.CSS_SELECTOR, '#sf2').click()
        else:
            print('未知乘客类型，请仔细检查配置文件')
            return

        # 点击查询车票
        self.driver.find_element(By.CSS_SELECTOR, '#query_ticket').click()

    # 车票预订
    def book_ticket(self):
        self.driver.find_element(By.CSS_SELECTOR, 'a.btn72:nth-child(1)').click()

        # 等待进入到车票详情页
        WebDriverWait(self.driver, 10).until(
            EC.element_to_be_clickable((By.CSS_SELECTOR, '#normalPassenger_0'))
        )
        self.driver.find_element(By.CSS_SELECTOR, '#normalPassenger_0').click()
        self.driver.find_element(By.CSS_SELECTOR, '#submitOrder_id').click()

        # 等待确认框出现
        WebDriverWait(self.driver, 10).until(
            EC.element_to_be_clickable((By.CSS_SELECTOR, '#qr_submit_id'))
        )
        self.driver.find_element(By.CSS_SELECTOR, '#qr_submit_id').click()



    # 主运行流程
    def run(self):
        try:
            # 加载Cookie
            self.load_cookies()
            # 检查登录状态
            if not self.login_status:
                # 1.实现登录逻辑
                flag = input('请选择登录的方式，输入1（账号密码登录），2（扫码登录）:')
                if flag == '1':
                    # 账号密码登录
                    self.account_password_login()
                elif flag == '2':
                    # 扫码登录
                    self.scan_code_login()
                else:
                    print('请检查输入是否正确，并重试～')
                    return

                # 保存Cookie
                self.save_cookies()

                # 车票查询
                self.query_ticket()
                # 车票预订TODO
                self.book_ticket()
        finally:
            # 关闭浏览器
            self.driver.quit()

if __name__ == "__main__":
    train = Train()
    train.run()